package com.teddy.controller;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.teddy.model.TaxonomyPool;
import com.teddy.model.ThesaurusPool;
import com.teddy.model.abstracts.SemanticObject;

import com.teddy.util.Constants;
import com.teddy.util.FileManager;
import com.teddy.util.DomUtil;
import com.teddy.model.Serializer;

public class ApplicationManager{
		
		private ThesaurusPool thesaurusPool;
		private TaxonomyPool taxonomyPool;
		private InputStream is;
		private Document workspaceDoc;

		private static ApplicationManager instance = null;
		
		protected ApplicationManager() throws IOException{
			is = this.getClass().getResourceAsStream("../../../"+Constants.LOAD_FILE);
			initPlugin();
		}
		
		public static ApplicationManager getInstance() throws IOException{
			if (instance == null){
				instance = new ApplicationManager();
			}
			return instance;
		}
		
		public void initPlugin() throws IOException{
			File f = new File (Constants.LOAD_FILE);
			if (!f.exists()){
				f.createNewFile();
				FileManager.writeFile(Constants.LOAD_FILE, is);
			}
		}
		
		public  void loadApplication() throws ParserConfigurationException, SAXException, IOException{
			thesaurusPool = new ThesaurusPool();
			taxonomyPool = new TaxonomyPool();
			
			workspaceDoc = DomUtil.fileToXmlDoc(Constants.LOAD_FILE);
			NodeList thNodes = workspaceDoc.getElementsByTagName(Constants.THESAURUS);
			NodeList taNodes = workspaceDoc.getElementsByTagName(Constants.TAXONOMY);
			
			for (int i=0; i < thNodes.getLength(); ++i){
				Element e=(Element)thNodes.item(i);
				SemanticObject so = new SemanticObject(e.getAttribute(Constants.NAME), e.getAttribute(Constants.FILE_PATH), true);
				so.addObserver(thesaurusPool);
				thesaurusPool.add(so);
			}
			
			for (int i=0; i < taNodes.getLength(); ++i){
				Element e=(Element)taNodes.item(i);
				taxonomyPool.add(new SemanticObject(e.getAttribute(Constants.NAME), e.getAttribute(Constants.FILE_PATH), false));
			}
		}
		
		public  ArrayList<SemanticObject> getThPoolMembers(){
		return thesaurusPool.getMembers();
		}
		
		public  ArrayList<SemanticObject> getTaxPoolMembers(){
			return taxonomyPool.getMembers();
		}
		
		
		public  SemanticObject importThesaurus(String uri){
			SemanticObject so = new SemanticObject(uri);
			thesaurusPool.add(so);
			updateWorkspace(so, Constants.ADD_TYPE);
			return so;
		}

		public void exportThesaurus(SemanticObject so){
			Serializer.serializeModel(so);
		}
		
		public void removeFromWorkspace(SemanticObject so){
			updateWorkspace(so, Constants.DELETE_TYPE);
		}
		
		
		private void updateWorkspace(SemanticObject so, String type){
			if (type.equals(Constants.ADD_TYPE)){
				Element e;
				if (so.isThesaurus)
					e = workspaceDoc.createElement(Constants.THESAURUS);
				else 
					e = workspaceDoc.createElement(Constants.TAXONOMY);
				e.setAttribute(Constants.NAME, so.getName());
				e.setAttribute(Constants.FILE_PATH, so.getURI());
				workspaceDoc.getFirstChild().appendChild(e);
			}
			if(type.equals(Constants.DELETE_TYPE)){
				 NodeList nodes = workspaceDoc.getFirstChild().getChildNodes();
				 System.out.print(nodes.getLength());
				 for (int i = 0; i< nodes.getLength(); ++i){
					 if(nodes.item(i).getNodeType() == Node.ELEMENT_NODE){
						 Element e = (Element) nodes.item(i);
						 if (e.getAttribute(Constants.FILE_PATH).equals(so.getURI())){
							 workspaceDoc.getFirstChild().removeChild(e);
							 break;
						 }
					 }
				 }
			}
			
			DomUtil.serializeDocument(Constants.LOAD_FILE, workspaceDoc);
		}
		/*
		 * Do not delete....V v v important stufffff:D
		 * 
		 * 
		 * 
		 * 
		 * 
		 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		 */
		/*public static void main(String args[]) throws ParserConfigurationException, SAXException, IOException{
			
			
			
			Model m = ModelFactory.createDefaultModel();
			 InputStream in =  com.hp.hpl.jena.util.FileManager.get().open( "C:/Users/Clumsy/MdLangCode.skos.xml" );
			if (in == null) {
			    throw new IllegalArgumentException(
			                                 "File: " + "C:/Users/Clumsy/MdLangCode.skos.xml" + " not found");
			}
			
			SKOSModel myMod = (SKOSModel) ModelFactory.createDefaultModel();
			myMod.read(in, null);
			
			
			//myMod.write(outputFile, encoding)
			m.read(in,null);
			m.write(System.out, "RDF/XML-ABBREV");
			/* Resource vcard = m.getResource("http://iaaa.cps.unizar.es/thesaurus/FORCED LABOUR");
			Writer output2 = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream("C:/Users/Clumsy/UNESCO2.skos.xml"), "UTF-8"));
			
			*/
			 // create an empty graph
	       /* Model model = ModelFactory.createDefaultModel();
	        
	       // create the resource
	       Resource r = model.createResource();                                     

	      // add the property
	      r.addProperty(RDFS.label, model.createLiteral("chat", "en"))
	       .addProperty(RDFS.label, model.createLiteral("chat", "fr"))
	       .addProperty(RDFS.label, model.createLiteral("<em>chat</em>", true));
	      
	      
	      Resource r1 = model.createResource(); 
	      
	      ResIterator it12 = m.listSubjects();      
	      
	      while (it12.hasNext()){
	    	 Resource rrr =  it12.next();
	    //	 System.out.println(rrr.getURI());
	    	System.out.println(rrr.getProperty(RDF.type).getResource().getURI());
	      }

	      // add the property
	      r1.addProperty(SKOS.prefLabel, model.createLiteral("fg", "en"))
	       .addProperty(SKOS.prefLabel, model.createLiteral("xc", "fr"));
	      
	     // System.out.println(r1.getProperty(SKOS.prefLabel));
	    /*  Statement p = r1.getProperty(SKOS.prefLabel);
	      StmtIterator it = r1.listProperties();
	      while(it.hasNext())
	      {
	    	  Statement s = it.nextStatement();
	    	  System.out.println(s.getPredicate().getLocalName());
	    	  System.out.println(s.getPredicate().getURI());
	    	  System.out.println(s.getLanguage());
	    	  System.out.println(s.getString());
	      }
	      */
	      // write out the graph
	  //    model.write(new PrintWriter(System.out));
	      
	      
	      // create an empty graph
	     /* model = ModelFactory.createDefaultModel();

	       // create the resource
	       r = model.createResource();                                     

	      // add the property
	      r.addProperty(RDFS.label, "11")
	       .addLiteral(RDFS.label, 11);
	      
	      // write out the graph
	    //  model.write( new PrintWriter(System.out));
		}*/
		

}
